#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017-09-25 16:14:13
# @Author  : WUQINGLONG
# @Contact : 1603763721@qq.com

# =======================================
# 优美胜于丑陋（Python 以编写优美的代码为目标）
# 明了胜于晦涩（优美的代码应当是明了的，命名规范，风格相似）
# 简洁胜于复杂（优美的代码应当是简洁的，不要有复杂的内部实现）
# 复杂胜于凌乱（如果复杂不可避免，那代码间也不能有难懂的关系，要保持接口简洁）
# 扁平胜于嵌套（优美的代码应当是扁平的，不能有太多的嵌套）
# 间隔胜于紧凑（优美的代码有适当的间隔，不要奢望一行代码解决问题）
# 可读性很重要（优美的代码是可读的）
# =======================================

"""
功能描述：
    1.一些装饰器的例子

"""

import signal
import functools
import sys
import os
import linecache


class TimeoutError(Exception):
    pass


def timeout(seconds, error_message='Function call timed out'):
    """运行时间限制装饰器，需要Linux支持"""

    def decorated(func):
        def _handle_timeout(signum, frame):
            raise TimeoutError(error_message)

        def wrapper(*args, **kwargs):
            # SIGALRM linux only
            signal.signal(signal.SIGALRM, _handle_timeout)
            signal.alarm(seconds)
            try:
                result = func(*args, **kwargs)
            finally:
                signal.alarm(0)
            return result

        return functools.wraps(func)(wrapper)

    return decorated


# @timeout(3)
# def slowfunc(sleep_time):
#     import time
#     time.sleep(sleep_time)
#     return sleep_time


def trace(f):
    """打印详细运行信息的装饰器"""

    def globaltrace(frame, why, arg):
        if why == "call":
            return localtrace
        return None

    def localtrace(frame, why, arg):
        if why == "line":
            # record the file name and line number of every trace
            filename = frame.f_code.co_filename
            lineno = frame.f_lineno
            bname = os.path.basename(filename)
            print("{}({}): {}".format(bname, lineno, linecache.getline(filename, lineno).strip('\r\n')))
        return localtrace

    def _f(*args, **kwds):
        sys.settrace(globaltrace)
        result = f(*args, **kwds)
        sys.settrace(None)
        return result

    return _f


if __name__ == '__main__':
    pass
